# Written on December 2008 by Giorgio Marciano' <ledzgio@writeme.com>
# a simple app that:
# a. well format each directory under source directory to destination directory
# b. also convert each mp3 file in source directory to open source ogg format
#
# Core module that contains the application behaviour
#
# GPL'd for her pleasure..
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.

import glob
from ID3 import *
import os
import sys
import shutil
import time
import threading
from StarUtilxGUI import StarUtilxGUI
import subprocess
try:
    import pygtk
    pygtk.require("2.0")
except:
    pass
try:
    import gtk
    import gtk.glade
except:
    sys.exit(1)

class ApplicationCore(threading.Thread):
    def __init__(self, gui):
        threading.Thread.__init__(self)
        self.gui = gui
        
    def run(self):
        pass
        
    def exec_format(self):
        #counters for the final report
        self.completed = 0
        self.skipped = 0
        self.nonaudio = 0
        self.notags = 0
        self.nomp3 = 0
        
        self.flag = self.gui.wTree.get_widget("option2").get_active()
        self.flag_convert = self.gui.wTree.get_widget("option3").get_active()
        
        #list that contains the skipped directory
        list_skipped = []
        infos = []
        origin = self.gui.wTree.get_widget("source_chooser").get_current_folder()
        destination = self.gui.wTree.get_widget("dest_chooser").get_current_folder()    
        
        try:
            list = os.listdir(origin)
            if len(list) == 0:
                self.gui.write_log("No files nor directories to process, exiting..")
                print "No files nor directories to process, exiting.."
                return
            self.gui.write_log("Found "+`len(list)`+" directories in \n"+origin)
            print "Found "+`len(list)`+" directories in \n"+origin
            
            #process each directory in the source directory
            for f in range(len(list)):
                current = os.path.join(origin,list[f])
                self.gui.write_log("Processing directory: \n"+current)
                print "Processing directory: \n"+current
                if os.path.isdir(current):
                    infos = self.get_tag_info(current)
                    
                    #if infos is a [] empty array then no files audio
                    #il infos is a None value then no tags
                    if infos == None:
                        self.notags += 1
                    if infos == []:
                        self.nomp3 += 1
                    if infos == None or infos == []:
                        if infos == []:
                            self.gui.write_log("No file audio, skip.")
                        self.skipped += 1
                        list_skipped.append(current)
                        path ="Unknown - Unknown"
                        continue
                    
                    path = infos[0] + " - " + infos[1] + " (" + infos[2] + ")"
                    dest = os.path.join(destination, path)
                    
                    #If destination path doesn't exist yet then make it
                    if not os.path.exists(dest):
                        
                        """filesystem operations"""
                        #if flag == True then the checkbox is checked and thus the directory will be deleted
                        if self.flag:
                            self.gui.write_log("Creating and moving to destination directory: \n"+dest)
                            os.mkdir(dest)
                            shutil.move(current, dest)
                            self.gui.write_log("Directory properly moved")
                            self.completed += 1
                        else:
                            self.gui.write_log("Copying directory to: \n"+dest)
                            shutil.copytree(current, dest)
                            self.gui.write_log("Directory properly copied")
                            self.completed += 1
                    
                    #else if exists then continue
                    else:
                        self.gui.write_log("Destination directory already exists. Skip.\n"+dest)
                        self.skipped += 1
                        list_skipped.append(current)
                        continue
                    
            #print the final report
            if len(list) != 0:
                self.gui.write_log("Done.\n"\
                              "Processed "+`len(list)`+" directory: \n"\
                              +`self.completed`+" with success\n"\
                              +`self.skipped`+" skipped ("+`self.nomp3`+" no-audio files, "+`self.notags`+" no-tags)\n"\
                              +`self.nonaudio`+" non audio files removed")
                
                #print the skipped files
                if ( len(list_skipped) > 0 ):
                    self.gui.write_log("Skipped:")
                    for i in range(len(list_skipped)):
                        self.gui.write_log(list_skipped[i])
            else:
                self.gui.write_log("No elements to process, exit.")
            
            #convert all files to ogg format
            if(self.flag_convert and infos != None and infos != []):
                self.gui.write_log("Conversion started")
                try:
                    #import thread
                    #thread.start_new_thread(self.convert, (destination,))
                    
                    #invoke convert2ogg module
                    from convert2ogg import convert
                    result = convert(self, destination)
                    time.sleep(1)
                    self.gui.write_log(result)
                    print "conversion completed."
                except:
                    print "Error in threading"
                    print sys.exc_info()[0]
                    print sys.exc_info()[1]
        except IOError, msg:
            print msg
            return
        except Exception, msg2:
            #print msg2
            print msg2
            print "Unknown error1, exitng app"
            return
    
    def get_tag_info(self, dir):
        try:
            
            dir_files = glob.glob(os.path.join(dir,"*.*"))
            #remove non audio files
            #non audio files will not removed whether the directory doesn't contain audio files
            self.remove_non_audio(dir_files)
            dir_files = glob.glob(os.path.join(dir,"*.mp3"))
            len_dir = len(dir_files)
            print "files into the selected directory: "+`len_dir`
            infos = []
            
            #if there are no files into the folder then return an empty list
            if len(dir_files) == 0:
                print "No files found, returning empty info list"
                return infos

            #pick up the first mp3 in list and extract ID3 tags info from it
            id3info = ID3(dir_files[0])
            self.gui.write_log("Retrieving ID3 tag info")
            infos = [id3info['ARTIST'], id3info['ALBUM'], id3info['YEAR']]
            print "ID3 tag info correctly retrieved: \n"+`infos`
            self.gui.write_log("ID3 tag info correctly retrieved: \n"+`infos`)
            return infos
        except InvalidTagError, msg:
            print "Invalid ID3 tag:", msg
            self.gui.write_log("Invalid ID3 tag: "+dir_files[0])
            return
        except KeyError, msg:
            print "Not tags in mp3 files: ",msg
            self.gui.write_log("Not tags in mp3 file:\n"\
                          +dir_files[0])
            return

    #read files and establish whether it is mp3 file or not
    def remove_non_audio(self, list):
        if len(list) == 0:
            self.gui.write_log("No files (non-audio) to remove")
            return
        else:
            for i in range(len(list)):
                leng = len(list[i])
                temp2 = (list[i])[leng-3:]
                if ( (temp2 != "mp3") and  (temp2 != "jpg") and (temp2 != "jpeg")\
                and (temp2 != "gif") and (temp2 != "JPG") and (temp2 != "m4a")\
                and (temp2 != "ogg") ) or (len(temp2) < 3): #remove other file
                    print "removing "+list[i]
                    self.gui.write_log("Found non audio file: "+list[i]+", removed.") 
                    os.remove(list[i])
                    self.nonaudio += 1